package com.xfzp.android.ms;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.opengl.Matrix;
import android.view.MotionEvent;

import com.xfzp.d3.Coord;
import com.xfzp.d3.Ray;

/**
 * 
 * @author AndroidApe
 * @version 2011-11-11
 */
public class GLView extends GLSurfaceView implements Renderer {
	private KubeSprite sprite;
	private boolean modeContinua;

	private int[] view;// 视窗，表示3D图形在屏幕上的可绘制范围
	private float[] project = new float[16];// 投影矩阵
	private float[] model = new float[16];// 模型观察矩阵

	public GLView(Context context, KubeSprite sprite) {
		super(context);
		this.sprite = sprite;

		modeContinua = false;
		// setBackgroundResource(R.drawable.bg_v);
		setLongClickable(true);
		// setZOrderOnTop(true);
		// getHolder().setFormat(PixelFormat.TRANSLUCENT);
		// setEGLConfigChooser(8, 8, 8, 8, 16, 0);
		setRenderer(this);
		setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
		gl.glShadeModel(GL10.GL_FLAT);// 使用恒定着色
		gl.glClearColor(0.5f, 0.5f, 0.5f, 1);// 设置清屏使用的颜色

		gl.glEnable(GL10.GL_DEPTH_TEST);// 启用深度测试
		gl.glDisable(GL10.GL_DITHER);// 关闭抖动，屏幕分辨率高时，不需要开启抖动
		gl.glEnable(GL10.GL_CULL_FACE);// 启用剔除面的功能，默认剔除反面

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		view = new int[] { 0, 0, width, height };
		float ratio = (float) width / height;
		Matrix.setIdentityM(project, 0);// 重置投影矩阵
		Matrix.frustumM(project, 0, -ratio, ratio, -1, 1, 2, 12);// 设置投影矩阵的视窗

		gl.glViewport(0, 0, width, height);// 设置3D图形在屏幕上的可绘制范围
		gl.glMatrixMode(GL10.GL_PROJECTION);// 选择投影矩阵
		gl.glLoadMatrixf(project, 0);// 装载投影矩阵
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存

		model = sprite.getModelView();
		gl.glMatrixMode(GL10.GL_MODELVIEW);// 选择模型观察矩阵
		gl.glLoadMatrixf(model, 0);// 装载模型观察矩阵

		if (sprite.draw(gl) && modeContinua) {
			modeContinua = false;
			setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent e) {
		if (modeContinua) {
			return super.onTouchEvent(e);
		}
		int a = e.getAction();
		float x, y;
		if (a == MotionEvent.ACTION_DOWN) {
			x = e.getX();
			y = e.getY();
			Coord orig = get3dCoord(x, y, 0);
			Coord dir = get3dCoord(x, y, 1).subtract(orig);
			sprite.down(x, y, new Ray(orig, dir));
		} else if (a == MotionEvent.ACTION_MOVE) {
			x = e.getX();
			y = e.getY();
			Coord end = get3dCoord(x, y, 0);
			sprite.move(x, y, end);
			requestRender();
		} else if (a == MotionEvent.ACTION_UP) {
			if (sprite.up()) {
				modeContinua = true;
				setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
			}
		}
		return super.onTouchEvent(e);
	}

	/**
	 * 返回平面坐标对应的三维坐标
	 * 
	 * @param x
	 * @param y
	 * @param z
	 * @return
	 */
	private Coord get3dCoord(float x, float y, float z) {
		float[] r = new float[4];
		y = view[3] - y;
		GLU.gluUnProject(x, y, z, model, 0, project, 0, view, 0, r, 0);

		for (int i = 0; i < 3; i++) {
			r[i] = r[i] / r[3];
		}
		return new Coord(r[0], r[1], r[2]);
	}
}
